package com.sora.pipeline.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sora.pipeline.common.api.ApiResponse;
import com.sora.pipeline.domain.*;
import com.sora.pipeline.domain.dto.*;
import com.sora.pipeline.service.*;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 统计报表控制器
 * 
 * @author system
 * @since 2025-01-20
 */
@RestController
@RequestMapping("/api/statistics")
@Validated
public class StatisticsController {

    @Autowired
    private InspectionTaskService inspectionTaskService;

    @Autowired
    private DefectService defectService;

    @Autowired
    private UserService userService;

    @Autowired
    private LineService lineService;

    @Autowired
    private DefectTypeService defectTypeService;

    @Autowired
    private DefectLevelService defectLevelService;

    @Autowired
    private RemedyTaskService remedyTaskService;

    @Autowired
    private OperationLogService operationLogService;

    @Autowired
    private RoleService roleService;

    /**
     * 1. 获取综合统计数据
     * 获取仪表盘统计数据
     */
    @GetMapping("/dashboard")
    public ApiResponse<DashboardStatisticsDTO> getDashboardStatistics(
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {

        // 设置默认日期范围（最近30天）
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
        }
        if (endDate == null) {
            endDate = LocalDate.now();
        }

        DashboardStatisticsDTO dashboard = new DashboardStatisticsDTO();

        // 获取任务统计数据
        dashboard.setTaskStats(getTaskStatistics(startDate, endDate));

        // 获取缺陷统计数据
        dashboard.setDefectStats(getDefectStatistics(startDate, endDate));

        // 获取人员统计数据
        dashboard.setPersonnelStats(getPersonStatistics());

//        // 获取地图热力图数据
        dashboard.setHeatmapData(null);

        return ApiResponse.success(dashboard);
    }

    /**
     * 2. 获取任务统计数据
     * 获取任务统计数据和趋势
     */
    @GetMapping("/tasks")
    public ApiResponse<TaskStatisticsDTO> getTaskStatistics(
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @RequestParam(required = false) Long lineId) {

        // 设置默认日期范围
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
        }
        if (endDate == null) {
            endDate = LocalDate.now();
        }

        TaskStatisticsDTO taskStats = getTaskStatistics(startDate, endDate);

        // 如果指定了线路ID，进行过滤
        if (lineId != null) {
            taskStats = filterTaskStatisticsByLine(taskStats, lineId);
        }

        return ApiResponse.success(taskStats);
    }

    /**
     * 3. 获取缺陷统计数据
     * 获取缺陷统计数据和分布
     */
    @GetMapping("/defects")
    public ApiResponse<DefectStatisticsDTO> getDefectStatistics(
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @RequestParam(required = false) Long lineId) {

        // 设置默认日期范围
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
        }
        if (endDate == null) {
            endDate = LocalDate.now();
        }

        DefectStatisticsDTO defectStats = getDefectStatistics(startDate, endDate);

        // 如果指定了线路ID，进行过滤
        if (lineId != null) {
            defectStats = filterDefectStatisticsByLine(defectStats, lineId);
        }

        return ApiResponse.success(defectStats);
    }

    /**
     * 4. 获取人员统计数据
     * 获取人员统计和绩效数据
     */
    @GetMapping("/personnel")
    public ApiResponse<PersonnelStatisticsDTO> getPersonnelStatistics() {
        PersonnelStatisticsDTO personnelStats = getPersonStatistics();
        return ApiResponse.success(personnelStats);
    }

    /**
     * 获取用户列表
     * 用于前端选择负责人等场景
     */
    @GetMapping("/users")
    public ApiResponse<List<UserOptionDTO>> getUsers() {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeleted, false)
                   .eq(User::getStatus, "active")  // 只返回活跃用户
                   .select(User::getId, User::getName, User::getUsername);
        
        List<User> users = userService.list(queryWrapper);
        
        List<UserOptionDTO> userOptions = users.stream()
            .map(user -> {
                UserOptionDTO dto = new UserOptionDTO();
                dto.setId(user.getId());
                dto.setName(user.getName() != null ? user.getName() : user.getUsername());
                return dto;
            })
            .collect(Collectors.toList());
        
        return ApiResponse.success(userOptions);
    }

    /**
     * 5. 获取地图热力图数据
     * 获取地图热力图位置数据
     */
//    @GetMapping("/heatmap")
//    public ApiResponse<HeatmapDataDTO> getHeatmapData(
//            @RequestParam(required = false) Long lineId) {
//
//        HeatmapDataDTO heatmapData = getHeatmapData();
//
//        // 如果指定了线路ID，进行过滤
//        if (lineId != null) {
//            heatmapData = filterHeatmapDataByLine(heatmapData, lineId);
//        }
//
//        return ApiResponse.success(heatmapData);
//    }

    /**
     * 6. 导出统计报表
     * 导出统计报表（Excel/PDF）
     */
    @GetMapping("/export")
    public ApiResponse<Map<String, Object>> exportStatistics(
            @RequestParam String type,
            @RequestParam(required = false) String format,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {

        // 设置默认格式
        if (format == null) {
            format = "excel";
        }

        // 设置默认日期范围
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
        }
        if (endDate == null) {
            endDate = LocalDate.now();
        }

        // 生成导出文件
        String fileName = generateExportFileName(type, format, startDate, endDate);
        String downloadUrl = generateDownloadUrl(fileName);

        Map<String, Object> result = new HashMap<>();
        result.put("fileName", fileName);
        result.put("downloadUrl", downloadUrl);
        result.put("expireTime", LocalDateTime.now().plusDays(7));

        return ApiResponse.success(result);
    }

    /**
     * 7. 获取自定义统计
     * 根据自定义条件获取统计数据
     */
    @PostMapping("/custom")
    public ApiResponse<Map<String, Object>> getCustomStatistics(@Valid @RequestBody StatisticsRequest request) {

        Map<String, Object> result = new HashMap<>();

        switch (request.getType()) {
            case "task":
                result.put("data", getTaskStatistics(request.getStartDate(), request.getEndDate()));
                break;
            case "defect":
                result.put("data", getDefectStatistics(request.getStartDate(), request.getEndDate()));
                break;
            case "personnel":
                result.put("data", getPersonnelStatistics());
                break;
//            case "heatmap":
//                result.put("data", getHeatmapData());
//                break;
            default:
                return ApiResponse.failure(60001, "统计类型不支持");
        }

        return ApiResponse.success(result);
    }

    /**
     * 获取任务统计数据
     */
    private TaskStatisticsDTO getTaskStatistics(LocalDate startDate, LocalDate endDate) {
        LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(InspectionTask::getDeleted, false)
                   .between(InspectionTask::getCreatedAt, startDate.atStartOfDay(), endDate.atTime(23, 59, 59));

        List<InspectionTask> tasks = inspectionTaskService.list(queryWrapper);

        TaskStatisticsDTO stats = new TaskStatisticsDTO();
        stats.setTotal((long) tasks.size());
        stats.setCompleted(tasks.stream().filter(t -> "completed".equals(t.getStatus())).count());
        stats.setPending(tasks.stream().filter(t -> "pending".equals(t.getStatus())).count());
        stats.setInProgress(tasks.stream().filter(t -> "in_progress".equals(t.getStatus())).count());

        if (stats.getTotal() > 0) {
            stats.setCompletionRate((double) stats.getCompleted() / stats.getTotal() * 100);
        } else {
            stats.setCompletionRate(0.0);
        }

        // 生成趋势数据
        stats.setTrend(generateTaskTrendData(startDate, endDate));

        return stats;
    }

    /**
     * 获取缺陷统计数据
     */
    private DefectStatisticsDTO getDefectStatistics(LocalDate startDate, LocalDate endDate) {
        LambdaQueryWrapper<Defect> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Defect::getDeleted, false)
                   .between(Defect::getCreatedAt, startDate.atStartOfDay(), endDate.atTime(23, 59, 59));

        List<Defect> defects = defectService.list(queryWrapper);

        DefectStatisticsDTO stats = new DefectStatisticsDTO();
        stats.setTotal((long) defects.size());

        // 按等级统计
        Map<String, Long> byLevel = defects.stream()
                .collect(Collectors.groupingBy(
                    d -> getDefectLevelName(d.getLevelId()),
                    Collectors.counting()
                ));
        stats.setByLevel(byLevel);

        // 按类型统计
        Map<String, Long> byType = defects.stream()
                .collect(Collectors.groupingBy(
                    d -> getDefectTypeName(d.getTypeId()),
                    Collectors.counting()
                ));
        stats.setByType(byType);

        // 生成趋势数据
        stats.setTrend(generateDefectTrendData(startDate, endDate));

        return stats;
    }

    /**
     * 获取人员统计数据
     */
    private PersonnelStatisticsDTO getPersonStatistics() {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeleted, false);

        List<User> users = userService.list(queryWrapper);

        PersonnelStatisticsDTO stats = new PersonnelStatisticsDTO();
        stats.setTotalUsers((long) users.size());
        stats.setActiveUsers(users.stream().filter(u -> u.getStatus() != null && u.getStatus().equals("active")).count());

        // 按角色统计
        Map<String, Long> byRole = users.stream()
                .collect(Collectors.groupingBy(
                    u -> getRoleName(u.getRoleId()),
                    Collectors.counting()
                ));
        stats.setByRole(byRole);

        // 生成绩效数据
        stats.setPerformance(generatePerformanceData());

        return stats;
    }

    /**
     * 获取地图热力图数据
     */
//    private HeatmapDataDTO getHeatmapData() {
//        List<Line> lines = lineService.list();
//
//        List<LocationDataDTO> locations = lines.stream()
//                .filter(line -> line.getStartLatitude() != null && line.getStartLongitude() != null)
//                .map(line -> {
//                    LocationDataDTO location = new LocationDataDTO();
//                    location.setLat(line.getStartLatitude());
//                    location.setLng(line.getStartLongitude());
//
//                    // 计算该线路的缺陷数量作为强度
//                    LambdaQueryWrapper<Defect> defectWrapper = new LambdaQueryWrapper<>();
//                    defectWrapper.eq(Defect::getLineId, line.getId())
//                                .eq(Defect::getDeleted, false);
//                    long defectCount = defectService.count(defectWrapper);
//
//                    location.setCount(defectCount);
//                    location.setIntensity(Math.min((int) (defectCount / 5 + 1), 10)); // 强度1-10
//
//                    return location;
//                })
//                .filter(location -> location.getCount() > 0)
//                .collect(Collectors.toList());
//
//        HeatmapDataDTO heatmapData = new HeatmapDataDTO();
//        heatmapData.setLocations(locations);
//
//        return heatmapData;
//    }

    /**
     * 生成任务趋势数据
     */
    private List<TrendDataDTO> generateTaskTrendData(LocalDate startDate, LocalDate endDate) {
        List<TrendDataDTO> trend = new ArrayList<>();

        LocalDate current = startDate;
        while (!current.isAfter(endDate)) {
            LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(InspectionTask::getDeleted, false)
                       .between(InspectionTask::getCreatedAt, current.atStartOfDay(), current.atTime(23, 59, 59));

            long count = inspectionTaskService.count(queryWrapper);

            TrendDataDTO trendData = new TrendDataDTO();
            trendData.setDate(current.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            trendData.setCount(count);
            trend.add(trendData);

            current = current.plusDays(1);
        }

        return trend;
    }

    /**
     * 生成缺陷趋势数据
     */
    private List<TrendDataDTO> generateDefectTrendData(LocalDate startDate, LocalDate endDate) {
        List<TrendDataDTO> trend = new ArrayList<>();

        LocalDate current = startDate;
        while (!current.isAfter(endDate)) {
            LambdaQueryWrapper<Defect> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Defect::getDeleted, false)
                       .between(Defect::getCreatedAt, current.atStartOfDay(), current.atTime(23, 59, 59));

            long count = defectService.count(queryWrapper);

            TrendDataDTO trendData = new TrendDataDTO();
            trendData.setDate(current.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            trendData.setCount(count);
            trend.add(trendData);

            current = current.plusDays(1);
        }

        return trend;
    }

    /**
     * 生成绩效数据
     */
    private List<PerformanceDTO> generatePerformanceData() {
        List<User> users = userService.list();

        return users.stream()
                .map(user -> {
                    LambdaQueryWrapper<InspectionTask> taskWrapper = new LambdaQueryWrapper<>();
                    taskWrapper.eq(InspectionTask::getAssigneeId, user.getId())
                              .eq(InspectionTask::getDeleted, false);

                    List<InspectionTask> userTasks = inspectionTaskService.list(taskWrapper);
                    long totalTasks = userTasks.size();
                    long completedTasks = userTasks.stream()
                            .filter(t -> "completed".equals(t.getStatus()))
                            .count();

                    PerformanceDTO performance = new PerformanceDTO();
                    performance.setName(user.getUsername());
                    performance.setTasksCompleted(completedTasks);

                    if (totalTasks > 0) {
                        performance.setCompletionRate((double) completedTasks / totalTasks * 100);
                    } else {
                        performance.setCompletionRate(0.0);
                    }

                    return performance;
                })
                .filter(p -> p.getTasksCompleted() > 0)
                .sorted((p1, p2) -> Long.compare(p2.getTasksCompleted(), p1.getTasksCompleted()))
                .limit(10)
                .collect(Collectors.toList());
    }

    /**
     * 按线路过滤任务统计数据
     */
    private TaskStatisticsDTO filterTaskStatisticsByLine(TaskStatisticsDTO stats, Long lineId) {
        // 这里可以实现按线路过滤的逻辑
        // 简化实现，返回原数据
        return stats;
    }

    /**
     * 按线路过滤缺陷统计数据
     */
    private DefectStatisticsDTO filterDefectStatisticsByLine(DefectStatisticsDTO stats, Long lineId) {
        // 这里可以实现按线路过滤的逻辑
        // 简化实现，返回原数据
        return stats;
    }

    /**
     * 按线路过滤热力图数据
     */
    private HeatmapDataDTO filterHeatmapDataByLine(HeatmapDataDTO heatmapData, Long lineId) {
        // 这里可以实现按线路过滤的逻辑
        // 简化实现，返回原数据
        return heatmapData;
    }

    /**
     * 获取缺陷等级名称
     */
    private String getDefectLevelName(Integer levelId) {
        if (levelId == null) {
            return "unknown";
        }
        DefectLevel level = defectLevelService.getById(levelId);
        return level != null ? level.getLevelName() : "unknown";
    }

    /**
     * 获取缺陷类型名称
     */
    private String getDefectTypeName(Integer typeId) {
        if (typeId == null) {
            return "unknown";
        }
        DefectType type = defectTypeService.getById(typeId);
        return type != null ? type.getTypeName() : "unknown";
    }

    /**
     * 获取角色名称
     */
    private String getRoleName(Integer roleId) {
        if (roleId == null) {
            return "unknown";
        }
        Role role = roleService.getById(roleId);
        return role != null ? role.getRoleName() : "unknown";
    }

    /**
     * 生成导出文件名
     */
    private String generateExportFileName(String type, String format, LocalDate startDate, LocalDate endDate) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        return String.format("%s_statistics_%s_%s.%s", type, startDate, endDate, format);
    }

    /**
     * 生成下载链接
     */
    private String generateDownloadUrl(String fileName) {
        return "/api/statistics/download/" + fileName;
    }
}

